home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / program / pdmake.arc / INPUT.C < prev    next >
C/C++ Source or Header  |  1986-12-15  |  9KB  |  359 lines

  1.     /***************************************************************\
  2.     *                                *
  3.     *  PDMAKE, Atari ST version                    *
  4.     *                                *
  5.     *  Adapted from mod.sources Vol 7 Issue 71, 1986-12-03.        *
  6.     *                                *
  7.     *  This port makes extensive use of the original net.sources    *
  8.     *  port by Jwahar Bammi.                    *
  9.     *                                *
  10.     *      Ton van Overbeek                        *
  11.     *      Email: TPC862@ESTEC.BITNET                *
  12.     *             TPC862%ESTEC.BITNET@WISCVM.WISC.EDU    (ARPA)    *
  13.     *             ...!mcvax!tpc862%estec.bitnet   (UUCP Europe)    *
  14.     *             ...!ucbvax!tpc862%estec.bitnet  (UUCP U.S.A.)    *
  15.     *             71450,3537  (CompuServe)                *
  16.     *                                *
  17.     \***************************************************************/
  18.  
  19. /*
  20.  *    Parse a makefile
  21.  */
  22.  
  23.  
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #include "h.h"
  27.  
  28.  
  29. struct name    namehead;
  30. struct name *    firstname;
  31.  
  32. char        str1[LZ];        /*  General store  */
  33. char        str2[LZ];
  34.  
  35.  
  36. /*
  37.  *    Intern a name.  Return a pointer to the name struct
  38.  */
  39. struct name *
  40. newname(name)
  41. char *        name;
  42. {
  43.     register struct name *    rp;
  44.     register struct name *    rrp;
  45.     register char *        cp;
  46.  
  47.  
  48.     for
  49.     (
  50.         rp = namehead.n_next, rrp = &namehead;
  51.         rp;
  52.         rp = rp->n_next, rrp = rrp->n_next
  53.     )
  54.         if (strcmp(name, rp->n_name) == 0)
  55.             return rp;
  56.  
  57.     if ((rp = (struct name *)malloc(sizeof (struct name)))
  58.                 == (struct name *)0)
  59.         fatal("No memory for name");
  60.     rrp->n_next = rp;
  61.     rp->n_next = (struct name *)0;
  62.     if ((cp = malloc(strlen(name)+1)) == (char *)0)
  63.         fatal("No memory for name");
  64.     strcpy(cp, name);
  65.     rp->n_name = cp;
  66.     rp->n_line = (struct line *)0;
  67.     rp->n_time = (time_t)0;
  68.     rp->n_flag = 0;
  69.  
  70.     return rp;
  71. }
  72.  
  73.  
  74. /*
  75.  *    Add a dependent to the end of the supplied list of dependents.
  76.  *    Return the new head pointer for that list.
  77.  */
  78. struct depend *
  79. newdep(np, dp)
  80. struct name *        np;
  81. struct depend *        dp;
  82. {
  83.     register struct depend *    rp;
  84.     register struct depend *    rrp;
  85.  
  86.  
  87.     if ((rp = (struct depend *)malloc(sizeof (struct depend)))
  88.                 == (struct depend *)0)
  89.         fatal("No memory for dependant");
  90.     rp->d_next = (struct depend *)0;
  91.     rp->d_name = np;
  92.  
  93.     if (dp == (struct depend *)0)
  94.         return rp;
  95.  
  96.     for (rrp = dp; rrp->d_next; rrp = rrp->d_next)
  97.         ;
  98.  
  99.     rrp->d_next = rp;
  100.  
  101.     return dp;
  102. }
  103.  
  104.  
  105. /*
  106.  *    Add a command to the end of the supplied list of commands.
  107.  *    Return the new head pointer for that list.
  108.  */
  109. struct cmd *
  110. newcmd(str, cp)
  111. char *        str;
  112. struct cmd *    cp;
  113. {
  114.     register struct cmd *    rp;
  115.     register struct cmd *    rrp;
  116.     register char *        rcp;
  117.  
  118.  
  119.     if (rcp = rindex(str, '\n'))
  120.         *rcp = '\0';            /*  Loose newline  */
  121.  
  122.     while (isspace(*str))
  123.         str++;
  124.  
  125.     if (*str == '\0')            /*  If nothing left, then exit  */
  126.         return;
  127.  
  128.     if ((rp = (struct cmd *)malloc(sizeof (struct cmd)))
  129.                 == (struct cmd *)0)
  130.         fatal("No memory for command");
  131.     rp->c_next = (struct cmd *)0;
  132.     if ((rcp = malloc(strlen(str)+1)) == (char *)0)
  133.         fatal("No memory for command");
  134.     strcpy(rcp, str);
  135.     rp->c_cmd = rcp;
  136.  
  137.     if (cp == (struct cmd *)0)
  138.         return rp;
  139.  
  140.     for (rrp = cp; rrp->c_next; rrp = rrp->c_next)
  141.         ;
  142.  
  143.     rrp->c_next = rp;
  144.  
  145.     return cp;
  146. }
  147.  
  148.  
  149. /*
  150.  *    Add a new 'line' of stuff to a target.  This check to see
  151.  *    if commands already exist for the target.  If flag is set,
  152.  *    the line is a double colon target.
  153.  *
  154.  *    Kludges:
  155.  *    i)  If the new name begins with a '.', and there are no dependents,
  156.  *        then the target must cease to be a target.  This is for .SUFFIXES.
  157.  *    ii) If the new name begins with a '.', with no dependents and has
  158.  *        commands, then replace the current commands.  This is for
  159.  *        redefining commands for a default rule.
  160.  *    Neither of these free the space used by dependents or commands,
  161.  *    since they could be used by another target.
  162.  */
  163. void
  164. newline(np, dp, cp, flag)
  165. struct name *    np;
  166. struct depend *    dp;
  167. struct cmd *    cp;
  168. {
  169.     bool            hascmds = FALSE; /*  Target has commands  */
  170.     register struct line *    rp;
  171.     register struct line *    rrp;
  172.  
  173.  
  174.     /* Handle the .SUFFIXES case */
  175.     if (np->n_name[0] == '.' && !dp && !cp)
  176.     {
  177.         for (rp = np->n_line; rp; rp = rrp)
  178.         {
  179.             rrp = rp->l_next;
  180.             free(rp);
  181.         }
  182.         np->n_line = (struct line *)0;
  183.         np->n_flag &= ~N_TARG;
  184.         return;
  185.     }
  186.  
  187.     /* This loop must happen since rrp is used later. */
  188.     for
  189.     (
  190.         rp = np->n_line, rrp = (struct line *)0;
  191.         rp;
  192.         rrp = rp, rp = rp->l_next
  193.     )
  194.         if (rp->l_cmd)
  195.             hascmds = TRUE;
  196.  
  197.     if (hascmds && cp && !(np->n_flag & N_DOUBLE))
  198.         /* Handle the implicit rules redefinition case */
  199.         if (np->n_name[0] == '.' && dp == (struct depend *)0)
  200.         {
  201.             np->n_line->l_cmd = cp;
  202.             return;
  203.         }
  204.         else
  205.             error("Commands defined twice for target %s", np->n_name);
  206.     if (np->n_flag & N_TARG)
  207.         if (!(np->n_flag & N_DOUBLE) != !flag)        /* like xor */
  208.             error("Inconsistent rules for target %s", np->n_name);
  209.  
  210.     if ((rp = (struct line *)malloc(sizeof (struct line)))
  211.                 == (struct line *)0)
  212.         fatal("No memory for line");
  213.     rp->l_next = (struct line *)0;
  214.     rp->l_dep = dp;
  215.     rp->l_cmd = cp;
  216.  
  217.     if (rrp)
  218.         rrp->l_next = rp;
  219.     else
  220.         np->n_line = rp;
  221.  
  222.     np->n_flag |= N_TARG;
  223.     if (flag)
  224.         np->n_flag |= N_DOUBLE;
  225. }
  226.  
  227.  
  228. /*
  229.  *    Parse input from the makefile, and construct a tree structure
  230.  *    of it.
  231.  */
  232. void
  233. input(fd)
  234. FILE *    fd;
  235. {
  236.     char *        p;        /*  General  */
  237.     char *        q;
  238.     struct name *    np;
  239.     struct depend *    dp;
  240.     struct cmd *    cp;
  241.     bool        dbl;
  242.  
  243.  
  244.     if (getline(str1, fd))        /*  Read the first line  */
  245.         return;
  246.  
  247.     for(;;)
  248.     {
  249. #ifdef os9
  250.         if (*str1 == ' ')        /*  Rules without targets  */
  251. #else
  252.         if (*str1 == '\t')        /*  Rules without targets  */
  253. #endif
  254.             error("Rules not allowed here");
  255.  
  256.         p = str1;
  257.  
  258.         while (isspace(*p))        /*  Find first target  */
  259.             p++;
  260.  
  261.         while (((q = index(p, '=')) != (char *)0) &&
  262.             (p != q) && (q[-1] == '\\'))    /*  Find value */
  263.         {
  264.             register char *        a;
  265.  
  266.             a = q - 1;            /*  Del \ chr; move rest back  */
  267.             p = q;
  268.             while(*a++ = *q++)
  269.                 ;
  270.         }
  271.  
  272.         if (q != (char *)0)
  273.         {
  274.             register char *    a;
  275.  
  276.             *q++ = '\0';        /*  Separate name and val  */
  277.             while (isspace(*q))
  278.                 q++;
  279.             if (p = rindex(q, '\n'))
  280.                 *p = '\0';
  281.  
  282.             p = str1;
  283.             if ((a = gettok(&p)) == (char *)0)
  284.                 error("No macro name");
  285.  
  286.             setmacro(a, q);
  287.  
  288.             if (getline(str1, fd))
  289.                 return;
  290.             continue;
  291.         }
  292.  
  293.         expand(str1);
  294.         p = str1;
  295.  
  296.         while (((q = index(p, ':')) != (char *)0) &&
  297.             (p != q) && (q[-1] == '\\'))    /*  Find dependents  */
  298.         {
  299.             register char *        a;
  300.  
  301.             a = q - 1;            /*  Del \ chr; move rest back  */
  302.             p = q;
  303.             while(*a++ = *q++)
  304.                 ;
  305.         }
  306.  
  307.         if (q == (char *)0)
  308.             error("No targets provided");
  309.  
  310.         *q++ = '\0';            /*  Separate targets and dependents  */
  311.  
  312.         if (*q == ':')            /*  Double colon */
  313.         {
  314.             dbl = 1;
  315.             q++;
  316.         }
  317.         else
  318.             dbl = 0;
  319.  
  320.         for (dp = (struct depend *)0; ((p = gettok(&q)) != (char *)0);)
  321.                     /*  get list of dep's */
  322.         {
  323.             np = newname(p);            /*  Intern name  */
  324.             dp = newdep(np, dp);        /*  Add to dep list */
  325.         }
  326.  
  327.         *((q = str1) + strlen(str1) + 1) = '\0';
  328.             /*  Need two nulls for gettok (Remember separation)